package de.fhd.pms.ctrl;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import de.fhd.pms.dao.AutomobilDao;
import de.fhd.pms.dao.DaoException;
import de.fhd.pms.dao.FahrtDao;
import de.fhd.pms.dao.StandortDao;
import de.fhd.pms.dao.TeilnehmerDao;
import de.fhd.pms.model.Automobil;

/**
 * Controller von Fahrt.
 * <p>
 * Der FahrtController übernimmt die Ablaufsteuerung für das Handling von
 * Fahrten (z. B. Userinput).
 * 
 * @author Martin Schmid
 * @author Florian Schachner
 */
@Controller
public class FahrtController {

	private static Logger log = Logger.getLogger(FahrtController.class);

	private FahrtDao fahrtDao = null;
	private TeilnehmerDao teilnehmerDao = null;
	private AutomobilDao automobilDao = null;
	private StandortDao standortDao = null;

	/*
	 * Schritt 3: SETZEN DER DAO-METHODEN: Setzen der FahrtDao um auf die
	 * tbl_fahrt zugreifen zu können; hier greift das IoC-Prinzip
	 * (Hollywood-Prinzip)
	 * "Ich erwarte, das mir jemand ein Dao-Objekt mitgibt (in application-context.xml definiert)"
	 */

	public void setFahrtDao(FahrtDao fahrtDao) {
		this.fahrtDao = fahrtDao;
	}

	/**
	 * SetTeilnehmerDao-Methode von FahrtController.
	 * <p>
	 * Hier wird der Input des Benutzers für einen Teilnehmer und für das Model
	 * gemappt.
	 * 
	 * @param teilnehmerDao
	 * @author Martin Schmid
	 * @author Florian Schachner
	 */
	public void setTeilnehmerDao(TeilnehmerDao teilnehmerDao) {
		this.teilnehmerDao = teilnehmerDao;
	}

	/**
	 * SetAutomobilDao-Methode von FahrtController.
	 * <p>
	 * Hier wird der Input des Benutzers für ein Automobil und für das Model
	 * gemappt.
	 * 
	 * @param automobilDao
	 * @author Martin Schmid
	 * @author Florian Schachner
	 */
	public void setAutomobilDao(AutomobilDao automobilDao) {
		this.automobilDao = automobilDao;
	}

	/**
	 * SetStandortDao-Methode von FahrtController.
	 * <p>
	 * Hier wird der Input des Benutzers für einen Standort und für das Model
	 * gemappt.
	 * 
	 * @param standortDao
	 * @author Martin Schmid
	 * @author Florian Schachner
	 */
	public void setStandortDao(StandortDao standortDao) {
		this.standortDao = standortDao;
	}

	/**
	 * BeginneFahrt-Methode von FahrtController.
	 * <p>
	 * Hierbei wird es ermöglicht, eine Fahrt zu beginnen. Diese Methode
	 * reagiert auf '/BeginneFahrt.html'. Abschließend wird die View mit Namen
	 * "editFahrt" aufgerufen.
	 * 
	 * @param autoID
	 *            - Integer
	 * @return Gibt ein Objekt vom Typ {@link ModelAndView} ("editFahrt")
	 *         zurück.
	 * @author Martin Schmid
	 * @author Florian Schachner
	 */
	@RequestMapping(value = "/BeginneFahrt.html", method = RequestMethod.GET)
	public ModelAndView beginneFahrt(@RequestParam(required = true) Integer autoID) {
		ModelAndView mv = new ModelAndView();
		if (teilnehmerDao.findFreieMitFahrerlaubnis().isEmpty() == true) {
			mv.addObject("title", "Fahrt eintragen");
			mv.addObject("message",	"Der Eintrag einer neuen Fahrt ist leider nicht möglich, da keine in Frage kommenden Teilnehmer existieren.");
			mv.setViewName("displayNoFahrtPossible");
		} else {
			mv.addObject("title", "Fahrt eintragen");
			mv.addObject("message", "Tragen Sie hier bitte die Person (einen Teilnehmer des CarSharing-Projekts) ein.");
			mv.addObject("automobil", automobilDao.findById(autoID));
			mv.addObject("teilnehmer", teilnehmerDao.findFreieMitFahrerlaubnis());
			mv.setViewName("editFahrt");
		}

		return mv;
	}

	/**
	 * Save-Methode von FahrtController.
	 * <p>
	 * Hierbei wird ein Fahrt anhand der Benutzereingaben gespeichert. Der Input
	 * wird an die entsprechende DAO-Instanz weitergegeben. Diese Methode
	 * reagiert auf '/SaveFahrt.html'.
	 * 
	 * @param autoID
	 *            - Integer
	 * @param tnID
	 *            - Integer
	 * @return Bei Erfolg einen Redirect mit dem Befehl 'index.html' und bei
	 *         Scheitern der Transaktion ein Objekt vom Typ {@link ModelAndView}
	 *         ("error") zurück.
	 * @author Martin Schmid
	 * @author Florian Schachner
	 */
	@RequestMapping(value = "/SaveFahrt.html", method = RequestMethod.POST)
	public ModelAndView save(@RequestParam(required = true) Integer autoID,	Integer tnID) {
		log.info("FAHRTCONTROLLER: SaveFahrt.html");

		try {
			fahrtDao.beginne(autoID, tnID);
			return new ModelAndView("redirect:AlleFahrten.html");
		} catch (DaoException e) {
			ModelAndView mv = new ModelAndView("error");
			mv.addObject("message", e.getMessage());
			return mv;
		}
	}

	/**
	 * FindAll-Methode von FahrtController.
	 * <p>
	 * Hierbei wird es ermöglicht, alle angelegten Fahrten in der Datenbank
	 * auszulesen. Diese Methode reagiert auf den Befehl '/AlleFahrten.html'.
	 * Alle gefundenen Fahrten werden dem ModelAndView-Objekt hinzugefügt.
	 * Abschließend wird die View mit Namen "listFahrten" aufgerufen.
	 * 
	 * @return Ein Objekt vom Typ {@link ModelAndView} ("listFahrten")
	 * @author Martin Schmid
	 * @author Florian Schachner
	 */
	@RequestMapping(value = "/AlleFahrten.html", method = RequestMethod.GET)
	public ModelAndView findAll() {
		ModelAndView mv = new ModelAndView();
		mv.addObject("title", "Fahrten");
		mv.addObject("message1", "Alle OFFENEN Fahrten im CarSharing-Projekt.");
		mv.addObject("message2", "Alle BEENDETEN Fahrten im CarSharing-Projekt.");
		mv.addObject("fahrten", fahrtDao.findAllDTO());
		mv.setViewName("listFahrten2");
		return mv;
	}

	/**
	 * Stop-Methode von FahrtController.
	 * <p>
	 * Hierbei wird es ermöglicht, offene Fahrten in der Datenbank zu
	 * beenden bzw. zu stoppen. Diese Methode reagiert auf den Befehl
	 * '/StopFahrt.html'. Alle gefundenen Fahrten werden dem ModelAndView-Objekt
	 * hinzugefügt. Abschließend wird die View mit Namen "closeFahrt"
	 * aufgerufen.
	 * 
	 * @param fahrtID
	 *            - Integer
	 * @return ein Objekt vom Typ {@link ModelAndView} ("closeFahrt")
	 * @author Martin Schmid
	 * @author Florian Schachner
	 */
	@RequestMapping(value = "/StopFahrt.html", method = RequestMethod.GET)
	public ModelAndView stop(@RequestParam(required = true) Integer fahrtID) {
		ModelAndView mv = new ModelAndView();
		mv.addObject("title", "Endkilometerstand eingeben");
		mv.addObject("message",	"Zum Abschluss der Fahrt bitte den aktuellen Kilometerstand laut Tacho eingeben.");
		mv.addObject("fahrt", fahrtDao.findById(fahrtID));
		mv.addObject("standort", standortDao.findAll());

		mv.setViewName("closeFahrt");
		return mv;
	}

	/**
	 * SaveFinal-Methode von FahrtController.
	 * <p>
	 * Hierbei wird eine beendete Fahrt anhand der Benutzereingaben als final
	 * gespeichert. Der Input wird an die entsprechende DAO-Instanz
	 * weitergegeben. Diese Methode reagiert auf '/BeendeFahrt.html'.
	 * 
	 * @param fahrtID
	 *            - Integer
	 * @param standortID
	 *            - Integer
	 * @param endekilometer
	 *            - Integer
	 * @return Einen Redirect mit dem Befehl 'index.html'
	 * @author Martin Schmid
	 * @author Florian Schachner
	 */
	@RequestMapping(value = "/BeendeFahrt.html", method = RequestMethod.POST)
	public String savefinal(@RequestParam(required = true) Integer fahrtID,	Integer standortID, Integer endekilometer) {
		fahrtDao.beende(fahrtID, standortID, endekilometer);
		return "redirect:AlleFahrten.html";
	}

}
